package tjs.study.mini.mybatismini.config;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import tjs.study.mini.mybatismini.config.proxy.MapperFactoryBean;

import java.util.Set;

/**
 * 自定义扫描逻辑
 * 对标以下类
 *
 * @author nicky
 * @date 2021/9/6 上午11:15
 * @see org.mybatis.spring.mapper.ClassPathMapperScanner
 */
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {

    public ClassPathMapperScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
        super(registry, useDefaultFilters);
    }

    /**
     * 重写父类，扫描逻辑
     *
     * @param basePackages
     * @return
     */
    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
        for (BeanDefinitionHolder holder : beanDefinitions) {
            AbstractBeanDefinition definition = (AbstractBeanDefinition) holder.getBeanDefinition();
            // 这里传入构造MapperFactoryBean所需要的参数mapperInterface
            definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName());
            // 生成代理的点
            definition.setBeanClass(MapperFactoryBean.class);
            // 自动装配成员属性setXXX
            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
        return beanDefinitions;
    }


    /**
     * 重写父类，是否为候选组件
     *
     * @param beanDefinition
     * @return
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        // 只扫描接口
        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
    }
}
